#ifndef  SPRITEANIMATE_HPP
# define SPRITEANIMATE_HPP

# include <SFML/Graphics.hpp>
# include "texturelist.hpp"
# include "observatory.hpp"

namespace Shiny
{
  class SpriteAnimate : public sf::Sprite
  {
  public:
    class Animation
    {
    public:
      Animation(void);
      Animation(const sf::Texture*);
      Animation(const Animation&);
      Animation(const AnimationList::Animation&);
      Animation(const sf::Texture*, sf::IntRect, unsigned short nFrames, float refresh, bool inLoop = true);

      void                     SetRefreshRate(float);
      void                     SetInLoop(bool);
      void                     operator()(SpriteAnimate*);
      void                     SetNextFrame(SpriteAnimate*);
      void                     Reset(void);
      const sf::Texture*       Texture(void) const;
      sf::Vector2f             Size(void) const;
      const sf::IntRect&       Rect(void) const { return (_rect); }

      unsigned short           NFrames(void) const          { return (_nFrames);     }
      float                    RefreshRate(void) const      { return (_refreshRate); }
      bool                     IsInLoop(void) const         { return (_inLoop);      }
      void                     SetTexture(sf::Texture* tex) { _image       = tex;    }
      void                     SetRect(sf::IntRect rect)    { _rect        = rect;   }
      void                     SetNFrames(unsigned short f) { _nFrames     = f;      }

    private:
      const sf::Texture*       _image;
      sf::IntRect              _rect;
      sf::Clock                _clock;
      unsigned short           _currentFrame;
      unsigned short           _nFrames;
      bool                     _inLoop;
      float                    _refreshRate;
    };

    friend class SpriteAnimate::Animation;
    typedef std::vector<Animation> AnimationArray;
    static AnimationArray LoadAnimations(Data, TextureList&, AnimationList&);
    static void           LoadAnimation(AnimationArray&, const std::string&, AnimationList&);
    static void           LoadTexture(AnimationArray&, const std::string&, TextureList&);

    SpriteAnimate(void);
    SpriteAnimate(const AnimationArray&);
    void         SetAnimations(const AnimationArray&);
    void         SetAnimation(unsigned int);
    unsigned int AnimationCount(void) const { return (_animations.size()); }
    void         Update(void);
    sf::Vector2f GetSize(void) const;
    void         FlipX(bool);
    void         FlipY(bool);

    virtual void SetTextureRect(const sf::IntRect& aabb);

    Observatory::Signal<unsigned int> AnimationFinished;

  private:
    bool           _flippedX, _flippedY;
    AnimationArray _animations;
    unsigned int   _currentAnimation;
  };
}

#endif // SPRITEANIMATE_HPP
